package qj.tool.gae;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import qj.util.Cols;
import qj.util.IOUtil;
import qj.util.funct.F1;

import com.google.apphosting.api.ApiProxy;

@SuppressWarnings("rawtypes")
public class ServletUtil {

	public static String getRequestString(HttpServletRequest req) {
		StringBuilder sb = new StringBuilder();

		for (Enumeration enu = req.getHeaderNames(); enu.hasMoreElements();) {
			String header = (String) enu.nextElement();
			sb.append(header + ": " + req.getHeader(header) + "\r\n");
		}
		sb.append("\r\n\r\n");
		
		appendRequestContent(req, sb);
		return sb.toString();
	}
	public static String getRequestContentString(HttpServletRequest req) {
		StringBuilder sb = new StringBuilder();
		appendRequestContent(req, sb);
		return sb.toString();
	}

	private static void appendRequestContent(HttpServletRequest req,
			StringBuilder sb) {
		String contentType = req.getHeader("Content-Type");
		if (contentType != null && contentType.toLowerCase().startsWith("multipart/form-data")) {
			try {
				sb.append(IOUtil.toString(req.getInputStream()));
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		} else if (contentType.startsWith("image")) {
			sb.append("((" + contentType + "))");
		} else {
		
			boolean first = true;
			for (Enumeration en = req.getParameterNames();en.hasMoreElements();) {
				String name = (String) en.nextElement();
				for (String val : req.getParameterValues(name)) {
					if (first) {
						first=false;
					} else {
						sb.append("&");
					}
					sb.append(name + "=" + val);
				}
			}
		}
	}

	public static String getHost() {
		return ApiProxy.getCurrentEnvironment().getAppId().replaceFirst("^s~", "");
	}

	public static String getHostFull(HttpServletRequest req) {
		Integer serverPort = req.getServerPort();
		String scheme = req.getScheme();
		if (
				(scheme.equals("http") && serverPort==80) ||
				(scheme.equals("https") && serverPort==443)
				) {
			serverPort=null;
		}
		String serverName = req.getServerName();
		if ("host".equals(serverName)) {
			serverName = "www.host.com";
		}
		return scheme + "://" + serverName + (serverPort==null? "" : ":" + serverPort);
	}

	public static String getCountry(final HttpServletRequest request) {
		return request.getHeader("X-AppEngine-Country");
	}

	public static String forceHttp(HttpServletRequest req) {
	
		Integer serverPort = req.getServerPort();
		String scheme = req.getScheme();
		if (
				(scheme.equals("http") && serverPort==80) ||
				(scheme.equals("https") && serverPort==443)
				) {
			serverPort=null;
		}
		String queryString = req.getQueryString();
		return "http://" + req.getServerName() + 
				(serverPort==null? "" : ":" + serverPort) + 
				req.getRequestURI() + (queryString != null ? "?"+queryString : "");
	}

	static F1<String,String> cityConvert = new F1<String, String>() {public String e(String obj) {
		Map<String, String> map = Cols.<String,String>map("thanh pho ho chi minh", "HCM");
		String val = map.get(obj);
		return val==null ? obj : val;
	}};
	public static String clientInfo(HttpServletRequest req) {
		StringBuilder sb = new StringBuilder();
		addInfoHeader("X-AppEngine-Country", "Co", null, sb, req);
		addInfoHeader("X-AppEngine-Region", "Re", null, sb, req);
		addInfoHeader("X-AppEngine-City", "Ci", cityConvert, sb, req);
		return req.getRemoteAddr() + (sb.length() > 0 ? "-" + sb:"");
	}

	private static void addInfoHeader(String headerName, String key, F1<String,String> convertValue,
			StringBuilder sb, HttpServletRequest req) {
		String header = req.getHeader(headerName);
		if (header != null && !"?".equals(header) && !"null".equals(header)) {
			if (sb.length() > 0) {
				sb.append(",");
			}
			sb.append(key + "=" + (convertValue==null ? header : convertValue.e(header)));
		}
	}
	public static String getCookieValue(String name, HttpServletRequest req) {
		
		Cookie[] cookies = req.getCookies();
		if (cookies==null) {
			return null;
		}
		for (Cookie cookie : cookies) {
			if (name.equals(cookie.getName())) {
				return cookie.getValue();
			}
		}
		return null;
	}
}
